﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyProject01.TraingingTask
{
    class MessageQueue<T>
    {
        private Queue<T> _queue;
        private Semaphore _sem;
        public MessageQueue()
        {
            _queue = new Queue<T>();
            _sem = new Semaphore(0, 1000);
        }
        public void Enqueue(T item)
        {
            lock(_queue)
            {
                _queue.Enqueue(item);
            }
            _sem.Release();
        }
        public T Dequeue()
        {
            T item;
            _sem.WaitOne();
            lock (_queue)
            {
                item = _queue.Dequeue();
            }
            return item;
        }
        public T Dequeue(int msTime)
        {
            T item;
            if (_sem.WaitOne(msTime) == false)
                return default(T);

            lock (_queue)
            {
                item = _queue.Dequeue();
            }
            return item;
        }

        public int Count
        {
            get
            {
                int cnt;
                lock (_queue)
                    cnt = _queue.Count;
                return cnt;
            }
        }
    }
    class TrainingTaskCtrl
    {
        public const int TaskNumber = 8;

        private Thread[] _TreadArr;
        private MessageQueue<ITestCase> _queue;

        public void Start()
        {
            _queue = new MessageQueue<ITestCase>();
            _TreadArr = new Thread[TaskNumber];
            for(int i=0;i< _TreadArr.Length;i++)
            {
                _TreadArr[i] = new Thread(new ThreadStart(WorkMain));
                _TreadArr[i].Start();
            }
        }
        public void Stop()
        {
            for (int i = 0; i < _TreadArr.Length; i++)
            {
                _TreadArr[i].Abort();
            }
        }
        public void Add(ITestCase test)
        {
            _queue.Enqueue(test);
        }


        private void WorkMain()
        {
            ITestCase test;
            while(true)
            {
                test = _queue.Dequeue();
                test.Run();
            }

        }

    }
}
